# -*- coding: utf-8 -*-
from graphs.matrixgraph import MatrixGraph
import random
import math


class Generator():

    def __init__(self):
        pass

    def generate(self, vcount, factor, filename):
        if factor > 1:
            raise Exception('Invalid density factor.')

        maxedges = (vcount - 1) * vcount
        ecount = int(maxedges * factor)

        if ecount < vcount:
            ecount = vcount

#        if ecount > 10000:
#            ecount = 10000
#        print 'Going for', ecount, 'edges.'

        graph = MatrixGraph()
        for i in range(vcount):
            name = 'V' + str(i)
            graph.add_vertex(name)

        #self.random_generation(graph, vcount, ecount)
        self.secuential_generation(graph, vcount, ecount)

        graph.save(filename)

    def random_generation(self, graph, vcount, ecount):
        for i in range(ecount):
            while True:
                edge = self.random_edge(vcount)
                if graph.get_edge(edge[0], edge[1]) is None:
                    graph.add_edge(edge[0], edge[1], edge[2])
                    break
                else:
                    print 'This edge already exists. Try again.'
                    print edge[0], edge[1], graph.edge_count()

    def secuential_generation(self, graph, vcount, ecount):
        edgespervertex = int(math.ceil(ecount / vcount))
        vdelta = int(vcount / edgespervertex)
        for src in range(vcount):
            if src % 100 == 0:
                print src
            for dest in range(src + 1, vcount + src + 1, vdelta):
                if dest >= vcount:
                    dest = dest - vcount
                if src != dest:
                    weight = random.randint(0, 10)
                    source = 'V' + str(src)
                    destination = 'V' + str(dest)
                    #print source, '-', destination, ':', weight
                    graph.add_edge(source, destination, weight)

    def random_edge(self, vcount, src=None):
        if src is None:
            src = random.randint(0, vcount - 1)

        dest = src
        while dest == src:
            dest = random.randint(0, vcount - 1)

        weight = random.randint(0, 10)
        src = 'V' + str(src)
        dest = 'V' + str(dest)

        return [src, dest, weight]
